package cn.com.cym.gamezao.service.impl;

import cn.com.cym.gamezao.base.BaseImpl;
import cn.com.cym.gamezao.base.BaseRepository;
import cn.com.cym.gamezao.base.SearchPage;
import cn.com.cym.gamezao.entity.Dict;
import cn.com.cym.gamezao.entity.DictItem;
import cn.com.cym.gamezao.repository.DictItemRepository;
import cn.com.cym.gamezao.service.DictItemService;
import cn.com.cym.gamezao.util.CommonUtils;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReflectUtil;
import lombok.SneakyThrows;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class DictItemImpl extends BaseImpl<DictItem> implements DictItemService {

    final DictItemRepository thisRepository;

    public  DictItemImpl(DictItemRepository thisRepository){
        this.thisRepository=thisRepository;
    }


    @Override
    public BaseRepository<DictItem, Long> getJpaRepository() {
        return thisRepository;
    }

    @Override
    public Page<DictItem> findByPageable(SearchPage searchPage) {
        String[] sortBy = searchPage.getSortBy().toArray(new String[searchPage.getSortBy().size()]);

        Pageable pageable = PageRequest.of(searchPage.getCurrent()-1, searchPage.getPageSize(), searchPage.getSort(), sortBy);

        Specification<DictItem> specification = new Specification<>() {

            private static final long serialVersionUID = -2661077778894635593L;

            /**
             * @param root: 代表查询的实体类.
             * @param query: 可以从中可到 Root 对象, 即告知 JPA Criteria 查询要查询哪一个实体类. 还可以
             * 来添加查询条件, 还可以结合 EntityManager 对象得到最终查询的 TypedQuery 对象.
             * @param  cb: CriteriaBuilder 对象. 用于创建 Criteria 相关对象的工厂. 当然可以从中获取到 Predicate 对象
             * @return  Predicate 类型, 代表一个查询条件.
             */
            @SneakyThrows
            @Override
            public Predicate toPredicate(Root<DictItem> root,
                                         CriteriaQuery<?> query, CriteriaBuilder cb) {
                final Map<String, Field> fieldMap = ReflectUtil.getFieldMap(DictItem.class);
                return cb.and(CommonUtils.pageSet(fieldMap,searchPage,cb,root));
            }
        };
        return this.thisRepository.findAll(specification, pageable);
    }

    @Override
    public List<DictItem> getAllVisible() {
        return thisRepository.findByDeleted(false);
    }

    @Override
    public List<DictItem> getByDict(Dict dict) {
        return this.thisRepository.getByDictAndDeleted(dict,false);
    }

    @Override
    public List<DictItem> getByDictId(Long dictId) {
        Dict dict=new Dict();
        dict.setId(dictId);
        return this.getByDict(dict);
    }

    @Override
    public DictItem getByCode(String code) {
        return this.thisRepository.getByCode(code,false);
    }

    @Override
    public DictItem updateByCode(DictItem dictItem, String code) {
        DictItem item = this.getByCode(code);
        if(item!=null && item.getId()!=null){
            BeanUtil.copyProperties(dictItem,item,true);
        }
        return super.save(dictItem);
    }

    @Override
    public DictItem save(DictItem dictItem) {
       /* if(dictItem.getId()==null){
            List<DictItem> byDictAndDeleted = this.thisRepository.getByDictAndDeleted(dictItem.getDict(), false);
            dictItem.getDict().setChildNums(byDictAndDeleted.size()+1);
        }*/
        return super.save(dictItem);
    }
}
